﻿using System.Collections.Generic;
using OpenTap.Plugins.Interfaces.Common;
using OpenTap.Plugins.Interfaces.MultiModeInstrument;
using OpenTap.Plugins.Interfaces.SCPI;

namespace OpenTap.Plugins.Interfaces.SA
{
    #region Enums

    public enum EClockSource
    {
        NotSet,
        Ext,
        Int
    }

    public enum EMeasurementSource
    {
        [Scpi("FILE")] File,
        [Scpi("DEV")] Device,
        [Scpi("INP")] Input
    }

    public enum EScale
    {
        NotSet,
        Low,
        Full
    }

    public enum ERoscSource
    {
        [Scpi("EXT")] Ext,
        [Scpi("INT")] Int
    }

    public enum EDetectorType
    {
        NotSet,
        [Scpi("NORM")] DetNorm,
        [Scpi("POS")] DetPos,
        [Scpi("NEG")] DetNeg,
        [Scpi("SAMP")] DetSamp,
        [Scpi("AVER")] DetAver,
        DetQuasiPeak,
        DetEmiAver,
        DetRmsAver,
        DetApeak
    }

    public enum EMeasurement
    {
        NotSet,
        MeasAcp,
        MeasEvm,
        MeasSa,
        MeasSem,
        MeasSpec,
        MeasCcdf,
        MeasChp
    }

    public enum EInputAttenuatorMode
    {
        NotSet,
        InputAttenuatorModeManual,
        InputAttenuatorModeAuto
    }

    public enum ESweepMode
    {
        NotSet,
        SweepmodeSingle,
        SweepmodeCont
    }

    public enum ESweepType
    {
        NotSet,
        [Scpi("AUTO")] SweepTypeAuto,
        [Scpi("SWE")] SweepTypeSweep,
        [Scpi("FFT")] SweepTypeFft,
        [Scpi("DRAN")] SweepTypeDynamicRange,
        [Scpi("SPE")] SweepTypeSpeed,
        [Scpi("OSW")] SweepTypeOnlySweep,
        [Scpi("PSW")] SweepTypePrioSweep,
        [Scpi("PFFT")] SweepTypePrioFft
    }

    public enum ESweepOptimization
    {
        NotSet,
        [Scpi("AUTO")] SweepOptAuto,
        [Scpi("SPE")] SweepOptSpeed,
        [Scpi("DYN")] SweepOptDyn
    }


    public enum E5GAcpStandard
    {
        NotSet,
        [Scpi("99MHZ_8CARR")] Bwid99Mhz8Carr,
        [Scpi("100MHZ_8CARR")] Bwid100Mhz8Carr
    }

    /// <summary>
    ///     Target where measurement setup if recalled
    ///     Instrument = physical instrument
    ///     PC = analysis software in PC, e.g. Keysight VSA
    /// </summary>
    public enum ESetupTarget
    {
        Instrument,
        Pc
    }

    public enum EAcpResultType
    {
        [Scpi("ALL")] All,
        [Scpi("CARR")] Carrier,
        [Scpi("OFFS")] Offset
    }

    public enum EAcpResultMode
    {
        [Scpi("A")] A,
        [Scpi("B")] B
    }

    public enum ESweepTimeMode
    {
        NotSet,
        SweeptimemodeManual,
        SweeptimemodeAuto
    }

    public enum ETriggerSource
    {
        [Scpi("IMM")] TriggerSourceFreeRun,
        [Scpi("VID")] TriggerSourceVideo,
        [Scpi("EXT1")] TriggerSourceExt1,
        [Scpi("EXT2")] TriggerSourceExt2,
        [Scpi("RFP")] TriggerSourceRfPower,
        [Scpi("SG")] TriggerSourceIfSgMarker,
        [Scpi("FRAM")] TriggerSourceFrame,
        [Scpi("RFB")] TriggerSourceRfBurst
    }

    public enum ERadioDirect
    {
        [Scpi("DLIN")] DownLink,
        [Scpi("ULIN")] UpLink
    }

    public enum ERadioConfig
    {
        [Scpi("CONF0")] Conf0,
        [Scpi("CONF1")] Conf1,
        [Scpi("CONF2")] Conf2,
        [Scpi("CONF3")] Conf3,
        [Scpi("CONF4")] Conf4,
        [Scpi("CONF5")] Conf5,
        [Scpi("CONF6")] Conf6,
        [Scpi("CONF7")] Conf7,
        [Scpi("CONF8")] Conf8
    }

    public enum EOffsetSide
    {
        [Scpi("BOTH")] Both,
        [Scpi("NEG")] Negative,
        [Scpi("POS")] Positive
    }

    public enum EEvmBandwidth
    {
        [Display("5", Order: 1)] Evmbw5 = 5000,
        [Display("10", Order: 2)] Evmbw10 = 10000,
        [Display("15", Order: 3)] Evmbw15 = 15000,
        [Display("20", Order: 4)] Evmbw20 = 20000,
        [Display("40", Order: 5)] Evmbw40 = 40000,
        [Display("100", Order: 6)] Evmbw100 = 100000
    }

    public enum Modulation
    {
        NotSet,
        [Scpi("DSQP")] DownlinkModulationQpsk,
        [Scpi("DSSF")] DownlinkModulation64Qam,
        [Scpi("DSST")] DownlinkModulation16Qam,
        [Scpi("DSTS")] DownlinkModulation256Qam,
        [Scpi("USQP")] UplinkModulationQpsk,
        [Scpi("USSF")] UplinkModulation64Qam,
        [Scpi("USST")] UplinkModulation16Qam,
        [Scpi("USTS")] UplinkModulation256Qam,
        [Scpi("PCH")] PhysicalChannel
    }

    public enum EGateType
    {
        [Scpi("LEV")] GateTypeLevel,
        [Scpi("EDGE")] GateTypeEdge
    }

    public enum EPolarity
    {
        [Scpi("NEG")] Negative,
        [Scpi("POS")] Positive
    }

    #endregion

    #region Classes

    /// <summary>
    /// SetupList uses to solve command sending order
    /// </summary>
    public class SetupList
    {
        public object SetupObject { get; set; }
        public int Order { get; set; }
    }

    /// <summary>
    /// Sweep settings
    /// </summary>
    public class Sweep
    {
        public Sweep()
        {
            SweepMode = ESweepMode.NotSet;
            SweepType = ESweepType.NotSet;
            SweepOptimization = ESweepOptimization.NotSet;
            SweepTime = double.NaN;
            SweepTimeMode = ESweepTimeMode.NotSet;
        }

        public ESweepMode SweepMode { get; set; }
        public ESweepType SweepType { get; set; }
        public ESweepOptimization SweepOptimization { get; set; }
        public double SweepTime { get; set; }
        public ESweepTimeMode SweepTimeMode { get; set; }

        public Sweep ShallowCopy()
        {
            return (Sweep) MemberwiseClone();
        }
    }

    /// <summary>
    /// Frequency and Span
    /// </summary>
    public class Frequency
    {
        public Frequency()
        {
            CenterFrequencyMhz = double.NaN;
            SpanMhz = double.NaN;
        }

        public double CenterFrequencyMhz { get; set; }
        public double SpanMhz { get; set; }

        public Frequency ShallowCopy()
        {
            return (Frequency) MemberwiseClone();
        }
    }

    /// <summary>
    /// Carrier settings
    /// </summary>
    public class Carrier
    {
        public Carrier()
        {
            CarrierCount = int.MinValue;
            CarrierSpacing = new List<double> {double.NaN};
            CarrierBandwidth = new List<double> {double.NaN};
            OffsetBandwidth = new List<double> {double.NaN};
            OffsetSpacing = new List<double> {double.NaN};
            OffsetState = new List<EState> {EState.NotSet};
        }

        public int CarrierCount { get; set; }
        public List<double> CarrierSpacing { get; set; }
        public List<double> CarrierBandwidth { get; set; }
        public List<EState> OffsetState { get; set; }
        public List<double> OffsetBandwidth { get; set; }
        public List<double> OffsetSpacing { get; set; }

        public Carrier ShallowCopy()
        {
            return (Carrier) MemberwiseClone();
        }
    }

    /// <summary>
    /// Average state and count
    /// </summary>
    public class Average
    {
        public Average()
        {
            AverageState = EState.NotSet;
            AverageCount = int.MinValue;
        }

        public EState AverageState { get; set; }
        public int AverageCount { get; set; }

        public Average ShallowCopy()
        {
            return (Average) MemberwiseClone();
        }
    }

    /// <summary>
    /// Sets Instrument mode , measurement and AcpStandard (AcpStandardMS2850A only)
    /// If measurement mode changes, also clears saved state machine parameters
    /// </summary>
    public class InstrumentState
    {
        public InstrumentState()
        {
            InstrumentMode = EInstrumentMode.NotSet;
            Measurement = EMeasurement.NotSet;
            AcpStandard = E5GAcpStandard.NotSet;
        }

        public EInstrumentMode InstrumentMode { get; set; }
        public EMeasurement Measurement { get; set; }
        public E5GAcpStandard AcpStandard { get; set; }

        public InstrumentState ShallowCopy()
        {
            return (InstrumentState) MemberwiseClone();
        }
    }

    /// <summary>
    /// Clears state machine saved parameter values if selected
    /// </summary>
    public class ClearParameters
    {
        public EState ClearStateMachineParameters { get; set; }
    }

    /// <summary>
    /// Handles attenuator mode and value
    /// </summary>
    public class Attenuator
    {
        public Attenuator()
        {
            AttenuatorMode = EInputAttenuatorMode.NotSet;
            InputAttenuator = int.MinValue;
        }

        public EInputAttenuatorMode AttenuatorMode { get; set; }
        public int InputAttenuator { get; set; }

        public Attenuator ShallowCopy()
        {
            return (Attenuator) MemberwiseClone();
        }
    }

    /// <summary>
    /// Handles detector state
    /// </summary>
    public class Detector
    {
        public Detector()
        {
            DetectorType = EDetectorType.NotSet;
            TraceNumber = uint.MaxValue;
        }

        public EDetectorType DetectorType { get; set; }
        public uint TraceNumber { get; set; }

        public Detector ShallowCopy()
        {
            return (Detector) MemberwiseClone();
        }
    }

    /// <summary>
    /// Reference level value
    /// </summary>
    public class ReferenceLevel
    {
        public ReferenceLevel()
        {
            ReferenceLevelValue = double.NaN;
        }

        public double ReferenceLevelValue { get; set; }

        public ReferenceLevel ShallowCopy()
        {
            return (ReferenceLevel) MemberwiseClone();
        }
    }

    /// <summary>
    /// Noise correction state
    /// </summary>
    public class NoiseCorrection
    {
        public NoiseCorrection()
        {
            NoiseCorrectionState = EState.NotSet;
        }

        public EState NoiseCorrectionState { get; set; }

        public NoiseCorrection ShallowCopy()
        {
            return (NoiseCorrection) MemberwiseClone();
        }
    }

    /// <summary>
    /// I/Q swap state
    /// </summary>
    public class SwapIq
    {
        public SwapIq()
        {
            SwapIqState = EState.NotSet;
        }

        public EState SwapIqState { get; set; }

        public SwapIq ShallowCopy()
        {
            return (SwapIq) MemberwiseClone();
        }
    }

    /// <summary>
    /// Video bandwith value
    /// </summary>
    public class VideoBandwidth
    {
        public VideoBandwidth()
        {
            VideoBandwidthAuto = EState.NotSet;
            VideoBandWidthValue = double.NaN;
        }

        public EState VideoBandwidthAuto { get; set; }
        public double VideoBandWidthValue { get; set; }

        public VideoBandwidth ShallowCopy()
        {
            return (VideoBandwidth) MemberwiseClone();
        }
    }

    public class AnritsuEvm5GData
    {
        public double TotalEvmPeakAvg;
        public double TotalEvmPeakMax;
        public double TotalEvmPeakSubcarrierNumber;
        public double TotalEvmPeakSymbolNumber;
        public double TotalEvmResultValid;
        public double TotalEvmRmsAvg;
        public double TotalEvmRmskMax;
        public double UeRsXpdcchEvmPeakAvg;
        public double UeRsXpdcchEvmPeakMax;
        public double UeRsXpdcchEvmPeakSymbolNumber;
        public double UeRsXpdcchEvmResultValid;
        public double UeRsXpdcchEvmRmsAvg;
        public double UeRsXpdcchEvmRmskMax;
        public double UeRsXpdcchPeakSubcarrierNumber;
        public double UeRsXpdschEvmPeakAvg;
        public double UeRsXpdschEvmPeakMax;
        public double UeRsXpdschEvmPeakSymbolNumber;
        public double UeRsXpdschEvmResultValid;
        public double UeRsXpdschEvmRmsAvg;
        public double UeRsXpdschEvmRmskMax;
        public double UeRsXpdschPeakSubcarrierNumber;
        public double XPdcchEvmPeakAvg;
        public double XPdcchEvmPeakMax;
        public double XPdcchEvmPeakSymbolNumber;
        public double XPdcchEvmResultValid;
        public double XPdcchEvmRmsAvg;
        public double XPdcchEvmRmskMax;
        public double XPdcchPeakSubcarrierNumber;
        public double XPdsc16QamEvmPeakSubcarrierNumber;
        public double XPdsc64QamEvmPeakSubcarrierNumber;
        public double XPdsch16QamEvmPeakAvg;
        public double XPdsch16QamEvmPeakMax;
        public double XPdsch16QamEvmPeakSymbolNumber;
        public double XPdsch16QamEvmResultValid;
        public double XPdsch16QamEvmRmsAvg;
        public double XPdsch16QamEvmRmskMax;
        public double XPdsch64QamEvmPeakAvg;
        public double XPdsch64QamEvmPeakMax;
        public double XPdsch64QamEvmPeakSymbolNumber;
        public double XPdsch64QamEvmResultValid;
        public double XPdsch64QamEvmRmsAvg;
        public double XPdsch64QamEvmRmskMax;
        public double XPdschAllEvmPeakAvg;
        public double XPdschAllEvmPeakMax;
        public double XPdschAllEvmPeakSubcarrierNumber;
        public double XPdschAllEvmPeakSymbolNumber;
        public double XPdschAllEvmResultValid;
        public double XPdschAllEvmRmsAvg;
        public double XPdschAllEvmRmskMax;
        public double XPdschQpskEvmPeakAvg;
        public double XPdschQpskEvmPeakMax;
        public double XPdschQpskEvmPeakSubcarrierNumber;
        public double XPdschQpskEvmPeakSymbolNumber;
        public double XPdschQpskEvmResultValid;
        public double XPdschQpskEvmRmsAvg;
        public double XPdschQpskEvmRmskMax;
    }

    #region Result Classes

    /// <summary>
    ///     A class that contains results from ACP measurement
    /// </summary>
    public class AcpResult
    {
        public AcpResult()
        {
            AcpCarrierPower = new List<double>();
            AcpOffsetLowerAbsolute = new List<double>();
            AcpOffsetUpperAbsolute = new List<double>();
            AcpOffsetLowerRelative = new List<double>();
            AcpOffsetUpperRelative = new List<double>();
        }

        /// <summary>
        ///     Absolute power of ACP reference carrier [dBm]
        /// </summary>
        public double AcpReferencePower { get; set; }

        /// <summary>
        ///     Total absolute power of all carriers [dBm]
        /// </summary>
        public double AcpTotalCarrierPower { get; set; }

        /// <summary>
        ///     Absolute power of each individual carrier [dBm]
        /// </summary>
        public List<double> AcpCarrierPower { get; set; }

        /// <summary>
        ///     ACP upper offset results, relative to reference carrier power [dBc]
        ///     Starting from offset closest to carrier, above it
        /// </summary>
        public List<double> AcpOffsetUpperRelative { get; set; }

        /// <summary>
        ///     ACP upper offset results [dBm]
        ///     Starting from offset closest to carrier, above it
        /// </summary>
        public List<double> AcpOffsetUpperAbsolute { get; set; }

        /// <summary>
        ///     ACP lower offset results, relative to reference carrier power [dBc]
        ///     Starting from offset closest to carrier, below it
        /// </summary>
        public List<double> AcpOffsetLowerRelative { get; set; }

        /// <summary>
        ///     ACP lower offset results [dBm]
        ///     Starting from offset closest to carrier, below it
        /// </summary>
        public List<double> AcpOffsetLowerAbsolute { get; set; }
    }

    /// <summary>
    ///     A class that contains results from CHP measurement
    /// </summary>
    public class ChpResult
    {
        /// <summary>
        ///     Total Channel Power
        /// </summary>
        public double TotalChannelPower { get; set; }

        /// <summary>
        ///     Total Power Spectral Density
        /// </summary>
        public double TotalPowerSpectralDensity { get; set; }
    }

    /// <summary>
    ///     A class that contains results from EVM measurement
    /// </summary>
    public class EvmResult
    {
        /// <summary>
        ///     Ch1DataEVM [%]
        /// </summary>
        public double DataEvm { get; set; }

        /// <summary>
        ///     Frequency error [Hz]
        /// </summary>
        public double FreqError { get; set; }
    }

    /// <summary>
    ///     A class that contains results from Sem measurement
    /// </summary>
    public class SemResult
    {
        public double LowerOffSetA { get; set; }
        public double UpperOffSetA { get; set; }
        public double LowerOffSetB { get; set; }
        public double UpperOffSetB { get; set; }
        public double LowerOffSetC { get; set; }
        public double UpperOffSetC { get; set; }
        public double LowerOffSetD { get; set; }
        public double UpperOffSetD { get; set; }
        public double LowerOffSetE { get; set; }
        public double UpperOffSetE { get; set; }
        public double LowerOffSetF { get; set; }
        public double UpperOffSetF { get; set; }
    }

    /// <summary>
    ///     A class that contains results from CCDF measurement
    /// </summary>
    public class CcdfResult
    {
        public double PowerLevelPercentage10 { get; set; }
        public double PowerLevelPercentage1 { get; set; }
        public double PowerLevelPercentage0Dot1 { get; set; }
        public double PowerLevelPercentage0Dot01 { get; set; }
        public double PowerLevelPercentage0Dot001 { get; set; }
        public double PowerLevelPercentage0Dot0001 { get; set; }
    }

    #endregion

    #endregion

    public interface ISa : IInstrument, IScpi, IMultiModeInstrument
    {
        /// <summary>
        ///     Sets SA center frequency. Unit is MHz.
        /// </summary>
        /// <param name="freqInMhz"> The frequency value in MHz.</param>
        void SetCenterFrequency(double freqInMhz);

        /// <summary>
        ///     Gets SA center frequency.
        /// </summary>
        /// <returns>The center frequency value in MHz.</returns>
        double GetCenterFrequency();

        /// <summary>
        ///     Set Start Stop frequency.
        /// </summary>
        /// <param name="startFrequencyInMhz">spans start freq in MHz.</param>
        /// <param name="stopFrequencyInMhz">spans stop freq in MHz.</param>
        void SetStartStopFrequency(double startFrequencyInMhz, double stopFrequencyInMhz);

        /// <summary>
        ///     Get Start Stop frequency.
        /// </summary>
        /// <param name="startFrequencyMhz"></param>
        /// <param name="stopFrequencyMhz"></param>
        void GetStartStopFrequency(out double startFrequencyMhz, out double stopFrequencyMhz);

        /// <summary>
        ///     Set Display on or off.
        /// </summary>
        /// <param name="displayState"> Set display on/off.</param>
        void SetDisplayOnOff(EState displayState);

        /// <summary>
        ///     Sets SA span.
        /// </summary>
        /// <param name="spanInMhz"> The span in MHz.</param>
        void SetSpan(double spanInMhz);

        /// <summary>
        ///     Gets SA span.
        /// </summary>
        /// <returns>Span value in Hz.</returns>
        double GetSpan();

        /// <summary>
        ///     Set Trigger Source
        /// </summary>
        /// <param name="triggerSource">trigger source (IMM,VID,EXT,RFP,SG,FRM).</param>
        void SetTriggerSource(ETriggerSource triggerSource);

	    /// <summary>
    	///     Set Gate Status
	    /// </summary>
	    /// <param name="gateStatus"> gate status (off/on).</param>
	    /// <param name="gateViewStatus"> gate status view (off/on).</param>
	    void SetGateStatus(EState gateStatus, EState gateViewStatus);

        /// <summary>
        ///     Set Gate Delay
        /// </summary>
        /// <param name="gateDelayMs"> gate delay ms.</param>
        void SetGateDelay(double gateDelayMs);

        /// <summary>
        ///     Set Gate Length
        /// </summary>
        /// <param name="gateLengthMs"> gate length ms.</param>
        void SetGateLength(double gateLengthMs);

        /// <summary>
        ///     Set Gate View Time
        /// </summary>
        /// <param name="sweepTimeMs"> set gate view sweep time (ms).</param>
        /// <param name="startTimeMs"> set gate view start time (ms).</param>
        void SetGateViewTime(double sweepTimeMs, double startTimeMs);

        /// <summary>
        ///     Set Gate source
        /// </summary>
        /// <param name="source"> ETriggerSource </param>
        void SetGateSource(ETriggerSource source);

        /// <summary>
        ///  Set Trigger Level for gate use
        /// </summary>
        /// <param name="source">ETriggerSource</param>
        /// <param name="level">used level</param>
        void SetGateLevel(ETriggerSource source, double level);

        /// <summary>
        /// Sets gate mode
        /// </summary>
        /// <param name="type">Level or Edge</param>
        void SetGateMode(EGateType type);

        /// <summary>
        /// Sets gate polarity
        /// </summary>
        /// <param name="polarity">positive/negative</param>
        void SetGatePolarity(EPolarity polarity);

        /// <summary>
        /// Sets gate view parameters (Anritsu only)
        /// </summary>
        /// <param name="rbwAutoState">Auto on/off</param>
        /// <param name="rbwHz">resolution bandwidth</param>
        /// <param name="vbwAutoState">Auto on/off</param>
        /// <param name="vbwHz">video bandwidth</param>
        /// <param name="detector">detector type</param>
        /// <param name="freqMHz">frequency in MHz</param>
        void SetGateViewParameters(EState rbwAutoState, double rbwHz, EState vbwAutoState, double vbwHz,
            EDetectorType detector, double freqMHz);

        /// <summary>
        ///     Set Radio Direction
        /// </summary>
        /// <param name="direction"> UpLink or DownLink</param>
        void SetRadioDirection(ERadioDirect direction);

        /// <summary>
        ///     Set Radio Uplink DownLink  configuration
        /// </summary>
        /// <param name="radioconfig"> radio config (CONF1...CONF6).</param>
        void SetRadioUlDlConfiguration(ERadioConfig radioconfig);

        /// <summary>
        ///     Set Radio DW GP UP configuration
        /// </summary>
        /// <param name="radioconfig"> radio config (CONF1...CONF8).</param>
        void SetRadioDwGpUpConfiguration(ERadioConfig radioconfig);

        /// <summary>
        ///     Measure ACP
        /// </summary>
        /// <returns>ACP results</returns>
        AcpResult MeasureAcp();

        /// <summary>
        ///     Measure Channel Power
        /// </summary>
        /// <param name="ibwHz"> Integration bandwidth in Hz.</param>
        /// <returns>CHP results</returns>
        ChpResult MeasureChp(double ibwHz);

        /// <summary>
        ///     Measure EVM
        /// </summary>
        /// <returns>EVM results</returns>
        EvmResult MeasureEvm();

        /// <summary>
        ///     Measure EVM
        /// </summary>
        /// <param name="centerFreqMHz">Center frequency in MHz</param>
        /// <returns>EVM results</returns>
        EvmResult MeasureEvm(double centerFreqMHz);

        /// <summary>
        /// Measure EVM (Anritsu)
        /// </summary>
        /// <param name="centerFreqMHz">Center frequency in MHz</param>
        /// <param name="networkDrive">network drive letter</param>
        /// <param name="dataFolder">Local folder where captured IQ data files are stored.</param>
        /// <param name="swapIq">Swap I/Q data ON or OFF</param>
        /// <returns></returns>
        EvmResult MeasureEvm(double centerFreqMHz, string networkDrive, string dataFolder, EState swapIq);

        /// <summary>
        ///     Measure SEM
        /// </summary>
        /// <returns>SEM results</returns>
        SemResult MeasureSem();

        /// <summary>
        ///     Measure SEM
        /// </summary>
        /// <param name="centerFreqMHz">Center frequency in MHz</param>
        /// <returns>SEM results</returns>
        SemResult MeasureSem(double centerFreqMHz);

        /// <summary>
        ///     Measure CCDF
        /// </summary>
        /// <returns>CCDF results</returns>
        CcdfResult MeasureCcdf();

        /// <summary>
        ///     Measure CCDF
        /// </summary>
        /// <param name="centerFreqMHz">Center frequency in MHz</param>
        /// <returns>CCDF results</returns>
        CcdfResult MeasureCcdf(double centerFreqMHz);

        /// <summary>
        ///     Set Reference level.
        /// </summary>
        /// <param name="refLevelInDb">reference level in dB.</param>
        void SetReferenceLevel(double refLevelInDb);

        /// <summary>
        ///     Set measurement
        /// </summary>
        /// <param name="meas">Select measurement ACP, EVM, ...</param>
        void SetMeasurement(EMeasurement meas);

        /// <summary>
        ///     Set Input Attenuator
        /// </summary>
        /// <param name="attenuatorMode"> Attenuator mode</param>
        /// <param name="attenuatorValueDb"></param>
        void SetInputAttenuator(EInputAttenuatorMode attenuatorMode, int attenuatorValueDb);

        /// <summary>
        ///     Set Sweep Mode
        /// </summary>
        /// <param name="sweepMode">sweep mode (Single/Continuous).</param>
        void SetSweepMode(ESweepMode sweepMode);

        /// <summary>
        ///     Set Acp Carrier Spacing
        /// </summary>
        /// <param name="acpCarrierSpacingInMhz">carrier spacing.</param>
        void SetAcpCarrierSpacing(List<double> acpCarrierSpacingInMhz);

        /// <summary>
        ///     Set Acp Offsets Spacing
        /// </summary>
        /// <param name="offsetfrequencyInMhz"></param>
        void SetAcpOffsetsSpacing(List<double> offsetfrequencyInMhz);

        /// <summary>
        ///     Set Acp Offset states
        /// </summary>
        /// <param name="offsetStates">List of </param>
        void SetAcpOffsetsState(List<EState> offsetStates);

        /// <summary>
        ///     Set Acp Carrier Count
        /// </summary>
        /// <param name="carrierCount">carrier count.</param>
        void SetAcpCarrierCount(int carrierCount);

        /// <summary>
        ///     Set Acp Center Frequency
        /// </summary>
        /// <param name="centerFrequencyInMhz">ACP center frequency in MHz.</param>
        void SetAcpCenterFrequency(double centerFrequencyInMhz);

        /// <summary>
        ///     Set bandwidth(s) for Acp Carrier(s)
        /// </summary>
        /// <param name="acpCarrierBandwidthInMhz">ACP carrier bandwidth.</param>
        void SetAcpCarrierBandwidth(List<double> acpCarrierBandwidthInMhz);

        /// <summary>
        ///     Set Acp Offset Bandwidth
        /// </summary>
        /// <param name="acpOffsetBandwidthInMhz">ACP offset bandwidth.</param>
        void SetAcpOffsetBandwidth(List<double> acpOffsetBandwidthInMhz);

        /// <summary>
        ///     Set Reference Carrier
        /// </summary>
        /// <param name="referenceCarrier">reference carrier number.</param>
        void SetAcpReferenceCarrier(uint referenceCarrier);

        /// <summary>
        ///     Sets the ACP averaging ON/Off with given averaging value
        /// </summary>
        /// <param name="averagingState">The averaging state ON/OFF</param>
        /// <param name="count">The used averaging value when averaging is set on. </param>
        void SetAcpAveraging(EState averagingState, int count = 0);

        /// <summary>
        ///     Searches the ACP peak power
        /// </summary>
        /// <param name="freqMhz">Peak frequency in MHz</param>
        /// <param name="powerDbm">Peak power in dBm</param>
        void GetAcpPeak(out double freqMhz, out double powerDbm);

        /// <summary>
        ///     Searches the peak power using marker
        /// </summary>
        /// <param name="markerNum">Marker number</param>
        /// <param name="freqMhz">Peak frequency in MHz</param>
        /// <param name="powerDbm">Peak power in dBm</param>
        void GetMarkerPeak(int markerNum, out double freqMhz, out double powerDbm);

        /// <summary>
        ///     Reads the value of the absolute power reference with ACP measurement.
        /// </summary>
        /// <returns>The ACP measurement reference level in dBm.</returns>
        double GetAcpReferenceLevel();

        /// <summary>
        ///     Sets the value for the absolute power reference with ACP measurement.
        /// </summary>
        /// <param name="refLevelIndBm">The ACP measurement reference level in dBm.</param>
        void SetAcpReferenceLevel(double refLevelIndBm);

        /// <summary>
        ///     Sets the CHP averaging ON/Off with given averaging value
        /// </summary>
        /// <param name="averagingState">The averaging state ON/OFF</param>
        /// <param name="count">The used averaging value when averaging is set on. </param>
        void SetChpAveraging(EState averagingState, int count = 0);

        /// <summary>
        ///     Set SEM Offset states
        /// </summary>
        /// <param name="offsetStates">List of </param>
        void SetSemOffsetsState(List<EState> offsetStates);

        /// <summary>
        ///     Set SEM Offset Side
        /// </summary>
        /// <param name="offsetSides">Max six offset side list</param>
        void SetSemOffsetSide(List<EOffsetSide> offsetSides);

        /// <summary>
        ///     Set SEM Offset Start Frequency
        /// </summary>
        /// <param name="frequenciesKHz">frequencies list</param>
        void SetSemOffsetStartFrequency(List<double> frequenciesKHz);

        /// <summary>
        ///     Set SEM Offset Stop Frequency
        /// </summary>
        /// <param name="frequenciesKHz">frequencies list</param>
        void SetSemOffsetStopFrequency(List<double> frequenciesKHz);

        /// <summary>
        ///     Set SEM Offset Absolute Limit Start
        /// </summary>
        /// <param name="limitStartsdBm">limit start list</param>
        void SetSemOffsetAbsoluteLimitStart(List<double> limitStartsdBm);

        /// <summary>
        ///     Set SEM Offset Absolute Limit Stop
        /// </summary>
        /// <param name="limitStopsdBm">limit stop list</param>
        void SetSemOffsetAbsoluteLimitStop(List<double> limitStopsdBm);

        /// <summary>
        ///     Set SEM Offset Relative Limit Start
        /// </summary>
        /// <param name="limitStartsdBm">limit relative start list</param>
        void SetSemOffsetRelativeLimitStart(List<double> limitStartsdBm);

        /// <summary>
        ///     Set SEM Offset Relative Limit Stop
        /// </summary>
        /// <param name="limitStopsdBm">limit relative stop list</param>
        void SetSemOffsetRelativeLimitStop(List<double> limitStopsdBm);

        /// <summary>
        ///     Set SEM Offset Measurement BandWidth Multiples
        /// </summary>
        /// <param name="multiples">Multiples list</param>
        void SetSemOffsetMeasurementBandWidthMultiples(List<int> multiples);

        /// <summary>
        ///     Set SEM Offset Resolution BandWidth
        /// </summary>
        /// <param name="frequencieskHz">frequencies list</param>
        void SetSemOffsetResolutionBandwidth(List<double> frequencieskHz);

        /// <summary>
        /// Set Evm Measurement Interval
        /// </summary>
        /// <param name="interval"></param>
        void SetEvmMeasurementInterval(int interval);

        /// <summary>
        /// Set Evm Starting Subframe Number
        /// </summary>
        /// <param name="startingSubframeNumber"> cant be bigger than 9.</param>
        void SetEvmStartingSubframeNumber(int startingSubframeNumber);

        /// <summary>
        ///     Sets the EVM averaging ON/Off with given averaging value
        /// </summary>
        /// <param name="averagingState">The averaging state ON/OFF</param>
        /// <param name="count">The used averaging value when averaging is set on. </param>
        void SetEvmAveraging(EState averagingState, int count = 0);

        /// <summary>
        ///     Sets the EVM measurement data source
        /// </summary>
        /// <param name="measureSource">Used types:File, Input, Device</param>
        void SetEvmMeasurementDataSource(EMeasurementSource measureSource);

        /// <summary>
        /// Restarts the current sweep, or measurement, or set of averaged/held sweeps or measurements
        /// </summary>
        void TriggerSweep();

        /// <summary>
        ///     Recall setup to instrument or analysis software
        /// </summary>
        /// <param name="setup">Setup file path and name</param>
        /// <param name="vseUsedChannel">Used Vse channel</param>
        /// <param name="vseMeasurementSource"></param>
        /// <param name="target">Setup target instrument / PC</param>
        void RecallSetup(string setup, string vseUsedChannel, EMeasurementSource vseMeasurementSource,
            ESetupTarget target);

        /// <summary>
        ///     Recall recorded IQ data for analysis
        /// </summary>
        /// <param name="recording">Setup file path and name</param>
        /// <param name="target">Setup target instrument / PC</param>
        /// <param name="sampleRateMhz">sample Rate Mhz (R&S only)</param>
        /// <param name="bandWidthMhz">bandwidth (R&S only)</param>
        void RecallRecording(string recording, ESetupTarget target, double sampleRateMhz, double bandWidthMhz);

        /// <summary>
        ///     Reads the value of the Video BandWidth.
        /// </summary>
        /// <returns>The Video BandWidth in MHz.</returns>
        double GetVideoBandWidth();


        /// <summary>
        ///     Sets the manual value for the Video BandWidth.
        /// </summary>
        /// <param name="bandWidthMhz">The Video BandWidth in MHz.</param>
        void SetVideoBandWidth(double bandWidthMhz);

        /// <summary>
        /// Set Bandwidth
        /// </summary>
        /// <param name="rbwHz"> Resolution bandwidth.</param>
        /// <param name="vbwHz"> Video bandwidth.</param>
        void SetBandwidth(double rbwHz, double vbwHz);

        /// <summary>
        ///     Sets the Video BandWidth to AUTO.
        /// </summary>
        void SetVideoBandWidthAuto();

        /// <summary>
        ///     Sets the channel BandWidth.
        /// </summary>
        /// <param name="channelBandwidth">The BandWidth in MHz.</param>
        void SetChannelBandwidth(EEvmBandwidth channelBandwidth);

        /// <summary>
        ///     Sets the BTS external Gain value.
        /// </summary>
        /// <param name="gainDb">The gain value in Db.</param>
        void SetChannelExternalGain(double gainDb);

        /// <summary>
        ///     Sets detector type
        /// </summary>
        /// <param name="detectorType">Used types: DetNorm,DetPos,DetNeg,DetSamp,DetAver,DetQuasiPeak,DetEmíAver,DetRmsAver</param>
        /// <param name="traceNumber">used trace</param>
        void SetDetectorType(EDetectorType detectorType, uint traceNumber);

        /// <summary>
        ///     Sets internal preamp state
        /// </summary>
        /// <param name="state">Off,On</param>
        void SetInternalPreampState(EState state);

        /// <summary>
        ///     Sets internal preamp scale
        /// </summary>
        /// <param name="scale">Low,Full</param>
        void SetInternalPreampScale(EScale scale);

        /// <summary>
        ///     Sets I/Q swap state
        /// </summary>
        /// <param name="swapState">ON or OFF</param>
        void SwapIq(EState swapState);

        /// <summary>
        ///     Sets sample Rate
        /// </summary>
        /// <param name="sampleRateMhz">used sample rate Mhz</param>
        void SetSampleRate(double sampleRateMhz);

        /// <summary>
        ///     Disconnects Instrument
        /// </summary>
        void DisconnectInstrument();

        /// <summary>
        ///     Set noise correction state
        /// </summary>
        /// <param name="noiseCorrectionState"></param>
        void SetNoiseCorrectionState(EState noiseCorrectionState);

        /// <summary>
        ///  Set sweep time
        /// </summary>
        /// <param name="sweepTimeMode">manual or auto</param>
        /// <param name="sweepTimeInSec">sweep time in sec</param>
        void SetSweepTime(ESweepTimeMode sweepTimeMode, double sweepTimeInSec);

        /// <summary>
        ///     Sets sweep type
        /// </summary>
        /// <param name="sweepType">AUTO,SWEep and FFT</param>
        void SetSweepType(ESweepType sweepType);

        /// <summary>
        ///     Sets sweep optimization state
        /// </summary>
        /// <param name="sweepOptimization">DYNamic,SPEed and AUTO</param>
        void SetSweepOptimization(ESweepOptimization sweepOptimization);

        /// <summary>
        ///     Setup instrument using object classes
        /// </summary>
        /// <param name="objects"></param>
        void SetupInstrument(params object[] objects);

        /// <summary>
        /// Sets alignment on
        /// </summary>
        void SetAlignmentOn();

        /// <summary>
        ///     Sets iq capture on and saves IQ data
        /// </summary>
        /// <param name="freqInMhz"></param>
        /// <param name="sampleRate"></param>
        /// <param name="sweepTimeInSec"></param>
        /// <param name="attenuatorMode"></param>
        /// <param name="attenuatorValue"></param>
        /// <param name="refLevel"></param>
        /// <param name="preAmpState"></param>
        /// <returns></returns>
        void SetIqCapture(double freqInMhz, double sampleRate, double sweepTimeInSec, EInputAttenuatorMode attenuatorMode,
            int attenuatorValue, double refLevel, EState preAmpState);

        /// <summary>
        ///     Measures and stores Iq data
        /// </summary>
        /// <param name="fileNameAndFolder"></param>
        void MeasureIq(string fileNameAndFolder);

        /// <summary>
        ///     Loads single signal description file (VSE only)
        /// </summary>
        /// <param name="allocationFile"></param>
        void LoadSingleDescriptionFile(string allocationFile);

        /// <summary>
        ///     Loads multiple signal description file (VSE only)
        /// </summary>
        /// <param name="ccAllocationFile"></param>
        void LoadMultipleDescriptionFile(string ccAllocationFile);

        /// <summary>
        ///     Measures NR5G evm (VSE only)
        /// </summary>
        /// <param name="centerFreqMHz">Center frequency</param>
        /// <param name="modulation">QPSK,16QAM,64QAM,256QAM or PhysicalChannel evm</param>
        /// <returns></returns>
        EvmResult MeasureNr5GEvm(double centerFreqMHz, Modulation modulation);

        /// <summary>
        ///     Restarts sweep all channels (VSE only)
        /// </summary>
        void RestartGroupSweep();

        /// <summary>
        ///     Selects Vse channel
        /// </summary>
        /// <param name="channelName">Used channel</param>
        void SelectChannel(string channelName);

        /// <summary>
        ///     Enables/Disables amplitude corrections
        /// </summary>
        /// <param name="enable"></param>
        void ApplyCorrections(bool enable);

        /// <summary>
        ///     Deletes the correction values for this set or ALL.
        /// </summary>
        /// <param name="corrSetNum">Correction Set Number</param>
        /// <param name="delAllCorr">If true, deletes ALL corrections</param>
        void DeleteCorrections(int corrSetNum, bool delAllCorr);

        /// <summary>
        ///     Enables/Disables selected complex correction.
        /// </summary>
        /// <param name="state">on or off</param>
        void SetComplexCorrectionState(EState state);

        /// <summary>
        ///     Turning the Selected Correction from the OFF state to the ON state allows the values in it to be applied to the
        ///     data.
        ///     This state transition also automatically turns on "Apply Corrections" (sets it to ON),
        ///     otherwise the correction would not take effect.
        /// </summary>
        /// <param name="state"></param>
        /// <param name="corrSetNum"></param>
        void SetCorrectionState(EState state, int corrSetNum);

        /// <summary>
        ///     Loads a csv file of correction values to the given set number.
        /// </summary>
        /// <param name="fileFolderAndName"></param>
        /// <param name="corrSetNum"></param>
        void LoadSourceCorrection(string fileFolderAndName, int corrSetNum);

        /// <summary>
        /// Captures screen shot on Xapps screen.
        /// </summary>
        /// <param name="fileFolderAndName"></param>
        void CaptureScreenShot(string fileFolderAndName);

        /// <summary>
        /// Sets averaging on or off
        /// </summary>
        /// <param name="state">on or off</param>
        void SetAverageState(EState state);

        /// <summary>
        /// Sets averaging count
        /// </summary>
        /// <param name="averageCount"></param>
        void SetAverage(uint averageCount);

        /// <summary>
        /// Sets sweep points
        /// </summary>
        /// <param name="points"></param>
        void SetSweepPoints(uint points);

        /// <summary>
        /// Configures CCDF measurement (ZVL only)
        /// </summary>
        /// <param name="rbwHz"></param>
        /// <param name="measurementPoints"></param>
        /// <param name="probability"></param>
        void ConfigCcdfMeasure(decimal rbwHz, uint measurementPoints, decimal probability);

        /// <summary>
        /// Set marker max and reads value
        /// </summary>
        /// <param name="markerNum">Marker number</param>
        /// <param name="freqMhz">Peak frequency in MHz</param>
        /// <param name="powerDbm">Peak power in dBm</param>
        void GetMarkerMax(int markerNum, out double freqMhz, out double powerDbm);
    }
}